﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Windows.Forms;

namespace Fractal
{
    public class MathClass
    {
        //正则表达式判断！是否符合阶数要求
        public static bool IsIterTimes(String strNumber)
        {
            Regex objNotNaturalPattern = new Regex("[^0-9]");
            Regex objNaturalPattern = new Regex("[2-9]");
            return !objNotNaturalPattern.IsMatch(strNumber) && objNaturalPattern.IsMatch(strNumber);
        }

        //正则表达式判断是否是自然数！！！！
        public static bool IsNaturalNumber(String strNumber)
        {
            Regex objNotNaturalPattern = new Regex("[^0-9]");
            Regex objNaturalPattern = new Regex("0*[1-9][0-9]*");
            return !objNotNaturalPattern.IsMatch(strNumber) && objNaturalPattern.IsMatch(strNumber);
        }

        #region 五个主要算法，绘制图形用！

        //东哥自创配色方案！
        public static void DrawColorfulJulia(PictureBox picBox)
        {
            //绘制julia集！！！！！！
            Bitmap t = new Bitmap(MathData.presetWidth, MathData.presetHeight);
            Graphics g = Graphics.FromImage(t);
            g.Clear(Color.White); //初始化，都刷成白色

            //BitmapData bmpData = t.LockBits(ClientRectangle, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

            int rdm100 = (int)(((double)MathData.rand / (double)MathData.RAND_MAX) * 100);//一百以内的自然数。用于对颜色随机赋值。

            double dp = ((double)MathData.pmax - (double)MathData.pmin) / MathData.presetWidth;
            double dq = ((double)MathData.qmax - (double)MathData.qmin) / MathData.presetHeight;

            for (int i = MathData.w_left; i < MathData.presetWidth; i++)
            {
                Application.DoEvents();
                for (int j = MathData.w_top; j < MathData.presetHeight; j++)
                {
                    MathData.x0 = (double)MathData.pmin + dp * i;
                    MathData.y0 = (double)MathData.qmin + dq * j;

                    for (int kk = 0; kk < MathData.m_Times; kk++)
                    {
                        getNextIter(MathData.iterTimes);
                        MathData.r = MathData.x * MathData.x + MathData.y * MathData.y;
                        MathData.x0 = MathData.x;
                        MathData.y0 = MathData.y;

                        if (MathData.r > MathData.m_deep)
                            break;

                        if (kk >= MathData.m_Times)
                        {
                            kk = (int)MathData.r;
                        }

                        MathData.th = (double)kk;
                    }
                    int k = (int)MathData.th;

                    MathData.red = (int)MathData.colorRound_table[((int)intpow(rdm100, MathData.rdmTimes_red) % MathData.csMaxColorRoundValue + k * MathData.rMover + MathData.trackBarColorMoverValue) % MathData.csMaxColorRoundValue];
                    MathData.green = (int)MathData.colorRound_table[((int)intpow(rdm100, MathData.rdmTimes_green) % MathData.csMaxColorRoundValue + k * MathData.rMover + MathData.trackBarColorMoverValue) % MathData.csMaxColorRoundValue];
                    MathData.blue = (int)MathData.colorRound_table[((int)intpow(rdm100, MathData.rdmTimes_blue) % MathData.csMaxColorRoundValue + k * MathData.rMover + MathData.trackBarColorMoverValue) % MathData.csMaxColorRoundValue];

                    Color c = Color.FromArgb(MathData.red, MathData.green, MathData.blue);
                    t.SetPixel(i, j, c);//这是最关键的函数，画点！
                }
            }
            picBox.Image = t;
        }

        //东哥自创配色方案！
        public static void DrawColorfulMandelbrot(PictureBox picBox)
        {
            //绘制Mandelbrot集！！！！
            Bitmap t = new Bitmap(MathData.presetWidth, MathData.presetHeight);
            Graphics g = Graphics.FromImage(t);
            g.Clear(Color.White); //初始化，都刷成白色

            double dp = (double)(MathData.pmax - MathData.pmin) / MathData.presetWidth;
            double dq = (double)(MathData.qmax - MathData.qmin) / MathData.presetHeight;

            int rdm100 = (int)(((double)MathData.rand / (double)MathData.RAND_MAX) * 100);//一百以内的自然数。用于对颜色随机赋值。

            for (int i = MathData.w_left; i < MathData.presetWidth; i++)
            {
                Application.DoEvents();
                for (int j = MathData.w_top; j < MathData.presetHeight; j++)
                {
                    MathData.x0 = 0;
                    MathData.y0 = 0;
                    MathData.p = (double)MathData.pmin + dp * i;//意思是让p和q取遍“参数窗口”（就是我们要观察的地方）上所有点，p是横坐标q是纵坐标。
                    MathData.q = (double)MathData.qmin + dq * j;

                    for (int kk = 0; kk < MathData.m_Times; kk++)
                    {
                        getNextIter(MathData.iterTimes);
                        MathData.r = MathData.x * MathData.x + MathData.y * MathData.y;
                        MathData.x0 = MathData.x;
                        MathData.y0 = MathData.y;
                        if (MathData.r > MathData.m_deep)//这代表r趋向于无穷大，所以就停下来，换下一个点继续迭代。
                            break;
                        MathData.th = (double)kk;
                    }
                    int k = (int)MathData.th;
                    MathData.red = (int)MathData.colorRound_table[((int)intpow(rdm100, MathData.rdmTimes_red) % MathData.csMaxColorRoundValue + k * MathData.rMover + MathData.trackBarColorMoverValue) % (MathData.csMaxColorRoundValue - 1)];
                    MathData.green = (int)MathData.colorRound_table[((int)intpow(rdm100, MathData.rdmTimes_green) % MathData.csMaxColorRoundValue + k * MathData.gMover + MathData.trackBarColorMoverValue) % (MathData.csMaxColorRoundValue - 1)];
                    MathData.blue = (int)MathData.colorRound_table[((int)intpow(rdm100, MathData.rdmTimes_blue) % MathData.csMaxColorRoundValue + k * MathData.bMover + MathData.trackBarColorMoverValue) % (MathData.csMaxColorRoundValue - 1)];

                    Color c = Color.FromArgb(MathData.red, MathData.green, MathData.blue);
                    t.SetPixel(i, j, c);//这是最关键的函数，画点！
                }
            }
            picBox.Image = t;
        }

        public static void DecimalJulia(PictureBox picBox)
        {
            //绘制julia集！！！！！！
            Bitmap t = new Bitmap(MathData.presetWidth, MathData.presetHeight);
            Graphics g = Graphics.FromImage(t);
            g.Clear(Color.White); //初始化，都刷成白色

            int rdm100 = (int)(((double)MathData.rand / (double)MathData.RAND_MAX) * 100);//一百以内的自然数。用于对颜色随机赋值。

            decimal dp = (MathData.pmax - MathData.pmin) / (MathData.presetWidth - MathData.w_left);
            decimal dq = (MathData.qmax - MathData.qmin) / (MathData.presetHeight - MathData.w_top);

            MathData.dec_pmax = Convert.ToDecimal(MathData.pmax); MathData.dec_pmin = Convert.ToDecimal(MathData.pmin); MathData.dec_qmax = Convert.ToDecimal(MathData.qmax); MathData.dec_qmin = Convert.ToDecimal(MathData.qmin);
            MathData.dec_p = Convert.ToDecimal(MathData.p); MathData.dec_q = Convert.ToDecimal(MathData.q);
            MathData.dec_dp = (MathData.dec_pmax - MathData.dec_pmin) / MathData.presetWidth; MathData.dec_dq = (MathData.dec_qmax - MathData.dec_qmin) / MathData.presetHeight;

            for (int i = MathData.w_left; i < MathData.presetWidth; i++)
            {
                Application.DoEvents();

                for (int j = MathData.w_top; j < MathData.presetHeight; j++)
                {
                    MathData.dec_x0 = MathData.dec_pmin + MathData.dec_dp * i;
                    MathData.dec_y0 = MathData.dec_qmin + MathData.dec_dq * j;

                    for (int kk = 0; kk < MathData.m_Times; kk++)
                    {
                        dec_getNextIter(MathData.iterTimes);
                        MathData.dec_r = MathData.dec_x * MathData.dec_x + MathData.dec_y * MathData.dec_y;
                        MathData.dec_x0 = MathData.dec_x;
                        MathData.dec_y0 = MathData.dec_y;

                        if (MathData.dec_r > MathData.m_deep)
                            break;
                        if (kk >= MathData.m_Times)
                        {
                            kk = (int)MathData.r;
                        }

                        MathData.th = (double)kk;
                    }
                    int k = (int)MathData.th;
                    MathData.red = (int)MathData.colorRound_table[((int)intpow(rdm100, MathData.rdmTimes_red) % MathData.csMaxColorRoundValue + k * MathData.rMover + MathData.trackBarColorMoverValue) % MathData.csMaxColorRoundValue];
                    MathData.green = (int)MathData.colorRound_table[((int)intpow(rdm100, MathData.rdmTimes_green) % MathData.csMaxColorRoundValue + k * MathData.rMover + MathData.trackBarColorMoverValue) % MathData.csMaxColorRoundValue];
                    MathData.blue = (int)MathData.colorRound_table[((int)intpow(rdm100, MathData.rdmTimes_blue) % MathData.csMaxColorRoundValue + k * MathData.rMover + MathData.trackBarColorMoverValue) % MathData.csMaxColorRoundValue];
                    
                    Color c = Color.FromArgb(MathData.red, MathData.green, MathData.blue);
                    t.SetPixel(i, j, c);//这是最关键的函数，画点！
                }
            }
            picBox.Image = t;
        }

        public static void DecimalMandelbrot(PictureBox picBox)
        {
            Bitmap t = new Bitmap(MathData.presetWidth, MathData.presetHeight);
            Graphics g = Graphics.FromImage(t);
            g.Clear(Color.White); //初始化，都刷成白色

            MathData.p = 0.57;//julia集的那个 C
            MathData.q = 0.046;

            int rdm100 = (int)(((double)MathData.rand / (double)MathData.RAND_MAX) * 100);//一百以内的自然数。用于对颜色随机赋值。

            decimal dp = (MathData.pmax - MathData.pmin) / (MathData.presetWidth - MathData.w_left);
            decimal dq = (MathData.qmax - MathData.qmin) / (MathData.presetHeight - MathData.w_top);

            MathData.dec_pmax = Convert.ToDecimal(MathData.pmax);
            MathData.dec_pmin = Convert.ToDecimal(MathData.pmin);
            MathData.dec_qmax = Convert.ToDecimal(MathData.qmax);
            MathData.dec_qmin = Convert.ToDecimal(MathData.qmin);
            MathData.dec_p = Convert.ToDecimal(MathData.p);
            MathData.dec_q = Convert.ToDecimal(MathData.q);
            MathData.dec_dp = (MathData.dec_pmax - MathData.dec_pmin) / MathData.presetWidth;
            MathData.dec_dq = (MathData.dec_qmax - MathData.dec_qmin) / MathData.presetHeight;

            for (int i = MathData.w_left; i < MathData.presetWidth; i++)
            {
                Application.DoEvents();

                for (int j = MathData.w_top; j < MathData.presetHeight; j++)
                {
                    MathData.dec_x0 = 0;
                    MathData.dec_y0 = 0;
                    MathData.dec_p = MathData.dec_pmin + MathData.dec_dp * i;
                    MathData.dec_q = MathData.dec_qmin + MathData.dec_dq * j;

                    for (int kk = 0; kk < MathData.m_Times; kk++)
                    {
                        dec_getNextIter(MathData.iterTimes);
                        MathData.dec_r = MathData.dec_x * MathData.dec_x + MathData.dec_y * MathData.dec_y;
                        MathData.dec_x0 = MathData.dec_x;
                        MathData.dec_y0 = MathData.dec_y;

                        if (MathData.dec_r > MathData.m_deep)
                            break;
                        if (kk >= MathData.m_Times)
                        {
                            kk = (int)MathData.r;
                        }
                        MathData.th = (double)kk;
                    }

                    int k = (int)MathData.th;

                    MathData.red = (int)MathData.colorRound_table[((int)intpow(rdm100, MathData.rdmTimes_red) % MathData.csMaxColorRoundValue + k * MathData.rMover + MathData.trackBarColorMoverValue) % MathData.csMaxColorRoundValue];
                    MathData.green = (int)MathData.colorRound_table[((int)intpow(rdm100, MathData.rdmTimes_green) % MathData.csMaxColorRoundValue + k * MathData.rMover + MathData.trackBarColorMoverValue) % MathData.csMaxColorRoundValue];
                    MathData.blue = (int)MathData.colorRound_table[((int)intpow(rdm100, MathData.rdmTimes_blue) % MathData.csMaxColorRoundValue + k * MathData.rMover + MathData.trackBarColorMoverValue) % MathData.csMaxColorRoundValue];

                    Color c = Color.FromArgb(MathData.red, MathData.green, MathData.blue);
                    t.SetPixel(i, j, c);//这是最关键的函数，画点！
                }
            }
            picBox.Image = t;
        }

        //算法来源于Kingblizzard屏幕保护程序
        public static void DrawNewton_Beta(PictureBox picBox)
        {
            Bitmap bmp = new Bitmap(MathData.presetWidth, MathData.presetHeight);
            Graphics g = Graphics.FromImage(bmp);
            g.Clear(Color.White); //初始化，都刷成白色
            Random randrand = new Random();

            double dp = (double)(MathData.pmax - MathData.pmin) / MathData.presetWidth;//很典型的逃逸时间算法，这个是比例因子
            double dq = (double)(MathData.qmax - MathData.qmin) / MathData.presetHeight;
            for (int x = 0; x < MathData.presetWidth; ++x)//这两重循环遍历了屏幕上所有点。
            {
                Application.DoEvents();

                double rx0 = x * dp + (double)MathData.pmin;
                for (int y = 0; y < MathData.presetHeight; ++y)
                {
                    double ry0 = y * dq + (double)MathData.qmin;
                    double dL1, dL2, dL3;
                    //这个bool变量在update()里面，我猜测应该是判断否用3次方程迭代
                    if (MathData.m_IsExtract3Ex)
                    {
                        //用牛顿三次方程迭代
                        getExtractByNewton_3Ex(rx0, ry0, MathData.m_iteratInc, out dL1, out dL2, out dL3);
                    }
                    else
                    {
                        //这个N次方程，指定次数的迭代。
                        getExtractByNewton(rx0, ry0, MathData.m_ExtractNumber, MathData.m_iteratInc, MathData.m_isTanRev, out dL1, out dL2, out dL3);
                    }
                    //得到颜色并且画点！
                    GetColor(dL1, dL2, dL3, out MathData.red, out MathData.green, out MathData.blue);

                    Color c = Color.FromArgb(MathData.red, MathData.green, MathData.blue);
                    bmp.SetPixel(x, y, c);
                }
            }
            picBox.Image = bmp;
        }

        #endregion

        #region 牛顿迭代专有的相关函数，包括 复数加减乘除，平方，N次方等等

        //ColorMover颜色初始值的初始化函数
        public static void CColorMoverInti(double kMin, double kMax)
        //参数取值！第一个不到50 第二个 不到90  
        {
            //颜色变化强度！
            MathData.m_kR = MathData.rand * (1.0 / MathData.RAND_MAX) * (kMax - kMin) + kMin; //40多到90之间的随机浮点数
            MathData.m_kG = MathData.rand * (1.0 / MathData.RAND_MAX) * (kMax - kMin) + kMin;
            MathData.m_kB = MathData.rand * (1.0 / MathData.RAND_MAX) * (kMax - kMin) + kMin;

            //初始颜色
            MathData.m_R0 = MathData.rand * (1.0 / MathData.RAND_MAX) * MathData.csMaxColorRoundValue; //0到512之间的随机浮点数
            MathData.m_G0 = MathData.rand * (1.0 / MathData.RAND_MAX) * MathData.csMaxColorRoundValue;
            MathData.m_B0 = MathData.rand * (1.0 / MathData.RAND_MAX) * MathData.csMaxColorRoundValue;
        }

        public static void Scene_Update(ulong StepTime_ms, double dNewton)//对一大堆随机值 进行更新操作！其中包括 颜色系数，迭代方程的次数
        {
            int[] ExtractNumberCountList = new int[11] { 3, 3, 3, 3, 4, 4, 5, 5, 6, 7, 8 };
            MathData.m_ExtractNumber = ExtractNumberCountList[MathData.rand % 11];//用于指定方程的次数！！！！居然在这里！
            MathData.m_IsExtract3Ex = (MathData.m_ExtractNumber == 3) && (MathData.rand > (MathData.RAND_MAX / 2));//用于指定 方程 是否是 三次方程！ 
            MathData.m_ColorK2 = dNewton;// Convert.ToDouble(textBoxNewton.Text);
            MathData.m_ColorK3 = MathData.m_ColorK2;
            MathData.m_ColorK1 = MathData.m_ColorK2 * MathData.m_ColorK2 * MathData.m_ColorK2;//这三个变量有关颜色！很神奇的变量，往后看 

            if (MathData.rand < (MathData.RAND_MAX / 2)) MathData.m_ColorK1 *= -1;
            if (MathData.rand < (MathData.RAND_MAX / 2)) MathData.m_ColorK2 *= -1;
            if (MathData.rand < (MathData.RAND_MAX / 2)) MathData.m_ColorK3 *= -1;//随机正负号！

            double r = 1.0 / (double)(1 << (int)(MathData.m_ExtractNumber - 3));
            r = Math.Pow(r, 0.095);//r大概在0.8到1之间
            MathData.m_ColorK1 *= r;
            MathData.m_ColorK2 *= r;
            MathData.m_ColorK3 *= r;//这又是干嘛呢？
            CColorMoverInti(50 * r, 90 * r);//初始化颜色        
            MathData.m_isTanRev = (MathData.rand > (MathData.RAND_MAX / 4));//一个概率 真假值，肯定是用于随机事件  
            if (MathData.m_isTanRev)//用这个来决定 牛顿迭代的循环次数！！！  
            {
                if (MathData.m_ExtractNumber == 3)
                {
                    MathData.m_iteratInc = 1 + (MathData.rand % 6);
                }
                else
                {
                    MathData.m_iteratInc = 1 + (MathData.rand % 4);
                }
            }
            else
            {
                MathData.m_iteratInc = 1 + (MathData.rand % 3);
            }
        }



        #region 复数四则运算和复角运算。永远都不变的函数，不用管
        const double eValue = 0.01;

        //重写Log函数，用于提高运算速度
        public static double mLog(double x)
        {
            if (x < eValue)
            {
                x = Math.Pow(x * (1.0 / eValue), 0.3) * eValue;
            }
            return Math.Log(x);
        }


        //平方
        public static double sqr(double x) { return x * x; }
        //X的 N次方！
        public static double intpow(double x, int N)
        {
            switch (N)
            {
                case 0: { return 1; };
                case 1: { return x; };
                case 2: { return x * x; };
                case 3: { return x * x * x; };
                case 4: { return sqr(x * x); };
                case 5: { return sqr(x * x) * x; };
                case 6: { return sqr(x * x * x); };
                default:
                    {
                        long half = N >> 1;//对应的二进制右移一位！其实就是除以2
                        double xh = sqr(intpow(x, (int)half));
                        if ((N & 1) == 0)
                            return xh;
                        else
                            return xh * x;
                    }
            }
        }


        //意思是把 复述平方！我学复动力系统图形生成之中的逃逸时间算法后才看明白
        public static void sqr(double x, double y, out double out_x, out double out_y)
        {
            out_x = x * x - y * y;
            out_y = 2 * x * y;
        }


        //复述乘法
        public static void mul(double x0, double y0, double x1, double y1, out double out_x, out double out_y)
        {
            out_x = x0 * x1 - y0 * y1;
            out_y = x0 * y1 + x1 * y0;
        }


        //复数的N次方！！！
        public static void pow(double x, double y, long N, out double out_x, out double out_y)
        {
            switch (N)
            {
                case 0: { out_x = 1; out_y = 0; } break;
                case 1: { out_x = x; out_y = y; } break;
                case 2: { sqr(x, y, out out_x, out out_y); } break;
                case 3: { double x1, y1; sqr(x, y, out x1, out y1); mul(x, y, x1, y1, out out_x, out out_y); } break;
                case 4: { double x1, y1; sqr(x, y, out x1, out y1); sqr(x1, y1, out out_x, out out_y); } break;
                case 5: { double x1, y1, x2, y2; sqr(x, y, out x1, out y1); sqr(x1, y1, out x2, out y2); mul(x, y, x2, y2, out out_x, out out_y); } break;
                case 6: { double x1, y1, x2, y2; sqr(x, y, out x1, out y1); sqr(x1, y1, out x2, out y2); mul(x1, y1, x2, y2, out out_x, out out_y); } break;
                default:
                    {
                        long half = N >> 1;
                        double xh, yh;
                        pow(x, y, half, out xh, out yh);
                        if ((N & 1) == 0)
                            sqr(xh, yh, out out_x, out out_y);
                        else
                        {
                            double xsqr, ysqr;
                            sqr(xh, yh, out xsqr, out ysqr);
                            mul(x, y, xsqr, ysqr, out out_x, out out_y);
                        }
                    } break;
            }
        }

        //显然是复数除法运算
        public static void div(double x0, double y0, double x1, double y1, ref double out_x, ref double out_y)
        {
            double r = 1 / (x1 * x1 + y1 * y1 + 1e-300);
            out_x = (x0 * x1 + y0 * y1) * r;
            out_y = (y0 * x1 - x0 * y1) * r;
        }


        //这个跟 复角有关
        public const double PI = 3.1415926535897932384626433832795;
        public static double asin2(double x, double y, double r)
        {
            double seta = Math.Asin(y / r);
            if (x >= 0)
                return seta;
            else if (y >= 0)
                return PI - seta;
            else
                return -PI - seta;
        }


        //“用牛顿法提取”？？注意，也是 三次方
        public static void getExtractByNewton_3Ex(double x0, double y0, long iteratInc, out double dL1, out double dL2, out double dL3)
        {
            x0 *= 0.75; y0 *= 0.75;
            //Z^3-1=0
            double x1 = x0, y1 = y0;
            for (long i = 0; i < iteratInc; ++i)
            {
                x0 = x1; y0 = y1;
                getNextPos_3Ex(x0, y0, ref x1, ref y1);//第三重循环
            }
            dL1 = mLog(Math.Abs(x1 - x0) * Math.Abs(y1 - y0)) * 0.6;
            dL2 = mLog(sqr(x1 - x0) + sqr(y1 - y0)) * 0.6;
            getNextPos_3Ex(x1, y1, ref x0, ref y0);
            dL3 = mLog(Math.Abs(x1 - x0) + Math.Abs(y1 - y0)) * 2.0;
        }


        //这是牛顿三次方程的迭代 3Ex表示三次方
        public static void getNextPos_3Ex(double x0, double y0, ref double out_x, ref double out_y)
        {
            double x2 = x0 * x0; double y2 = y0 * y0;
            double r = (1.0 / 6) / sqr(x2 + y2 + 1e-300);
            double a = x2 - y2;
            double b = x0 * y0 * 2;
            out_x = -y0 + (a - b) * r;
            out_y = x0 - (a + b) * r;
        }


        //可能是计算下一个坐标的函数
        public static void getNextPos(double x0, double y0, long N, bool isTanRev, ref double out_x, ref double out_y)
        {
            //Z^N-1=0
            double seta;
            if (isTanRev) seta = Math.Atan2(x0, y0); else seta = Math.Atan2(y0, x0);
            double r = Math.Sqrt(x0 * x0 + y0 * y0);
            r = r * (N - 1) / N;
            double sl = 1.0 / (N * intpow(r, (int)(N - 1)));
            out_x = (r * Math.Cos(seta) + sl * Math.Cos((1 - N) * seta));
            out_y = (r * Math.Sin(seta) + sl * Math.Sin((1 - N) * seta));


        }


        //这个是 N次方程，也是“用牛顿法提取”，提取出dL1 dL2 dL3三个值。
        public static void getExtractByNewton(double x0, double y0, long N, long iteratInc, bool isTanRev, out double dL1, out double dL2, out double dL3)
        {
            //Z^N-1=0
            double x1 = x0, y1 = y0;
            for (long i = 0; i < iteratInc; ++i)//万恶的第三重循环，原来在这里！
            {
                x0 = x1; y0 = y1;
                getNextPos(x0, y0, N, isTanRev, ref x1, ref y1);//典型的逃逸时间算法的内层循环。
            }//得到x1 y1和x0 y0的值，用于下面的计算

            dL1 = mLog(Math.Abs(x1 - x0) * Math.Abs(y1 - y0)) * 0.6;
            dL2 = mLog(sqr(x1 - x0) + sqr(y1 - y0)) * 0.6;

            getNextPos(x1, y1, N, isTanRev, ref x0, ref y0);
            dL3 = mLog(Math.Abs(x1 - x0) + Math.Abs(y1 - y0)) * 2.0;
        }



        #endregion


        //通过dL1 dL2 dL3得到 相对应的颜色信息，这是最具艺术性的一个函数。
        //请问！！这个是虚函数吗？一直没用过，只是在传说中看到过
        public static void GetColor(double dL1, double dL2, double dL3, out int red, out int green, out int blue)
        {
            double kR = dL1 * MathData.m_ColorK1 + dL2 * MathData.m_ColorK2 - dL3 * MathData.m_ColorK3;//这个配比很奇怪！不懂为啥这样
            double kG = dL1 * MathData.m_ColorK1 - dL2 * MathData.m_ColorK2 + dL3 * MathData.m_ColorK3;
            double kB = -dL1 * MathData.m_ColorK1 + dL2 * MathData.m_ColorK2 + dL3 * MathData.m_ColorK3;

            red = (int)(getColor(MathData.m_R0, MathData.m_kR, kR));
            green = (int)(getColor(MathData.m_G0, MathData.m_kG, kG));
            blue = (int)getColor(MathData.m_B0, MathData.m_kB, kB);

        }


        public static ulong getColor(double Color0, double k, double Gene)
        {

            uint rd = (uint)(Color0 + k * Gene);
            rd = rd % (uint)MathData.csMaxColorRoundValue;

            ulong temp = MathData.colorRound_table[rd];//返回的正好是 0到255之间的数，见数组的初始化函数！
            return temp;
        }



        public static long round_color(int x)
        {
            if (x < 0) x = -x;//取值变成  513到0，再到512。首尾相接
            while (x > MathData.csMaxColorRoundValue) x -= MathData.csMaxColorRoundValue;//最后x范围是 1 512 到0 再到512
            const double PI = 3.1415926535897932384626433832795;
            double rd = (Math.Sin(x * (2.0 * PI / MathData.csMaxColorRoundValue)) + 1.1) / 2.1;//色环！正好2pi转了一圈！
            //rd取值从 -0.1到1到0.1到1到-0.1
            long ri = (long)(rd * 255 + 0.5);
            //long ri=abs(x-csMaxColorRoundValue/2);
            if (ri < 0) return 0;
            else if (ri > 255) return 255;
            else return ri;
        }


        public static void Creat_colorRound_table()
        {
            for (int i = 0; i < (MathData.csMaxColorRoundValue + 1) * 2; i++)//首尾相接！为了柔和！太强大了！哈哈，明白了
                MathData.colorRound_table[i] = (ulong)round_color(i - (MathData.csMaxColorRoundValue + 1));//取值是 -513到+510！！太强大了！
        }//i是0到1023


        #endregion

        #region MJ集专有函数
        public static void getNextIter(int Times)
        {
            switch (Times)
            {
                case 2:
                    MathData.x = MathData.general_MJ2 * MathData.x0 * MathData.x0 - MathData.general_MJ3 * MathData.y0 * MathData.y0 + MathData.p;//对于给定的p和q，按照下面两行无限迭代。
                    MathData.y = MathData.general_MJ4 * 2 * MathData.x0 * MathData.y0 + MathData.q;
                    break;
                case 3:
                    MathData.x = MathData.general_MJ2 * MathData.x0 * MathData.x0 * MathData.x0 - MathData.general_MJ3 * 3 * MathData.x0 * MathData.y0 * MathData.y0 + MathData.p;
                    MathData.y = MathData.general_MJ4 * 3 * MathData.x0 * MathData.x0 * MathData.y0 - MathData.general_MJ5 * MathData.y0 * MathData.y0 * MathData.y0 + MathData.q;
                    break;
                case 4:
                    MathData.x = MathData.general_MJ2 * MathData.x0 * MathData.x0 * MathData.x0 * MathData.x0 - MathData.general_MJ3 * 6 * MathData.x0 * MathData.x0 * MathData.y0 * MathData.y0 + MathData.general_MJ4 * MathData.y0 * MathData.y0 * MathData.y0 * MathData.y0 + MathData.p;
                    MathData.y = MathData.general_MJ5 * 4 * MathData.x0 * MathData.x0 * MathData.x0 * MathData.y0 - MathData.general_MJ5 * 4 * MathData.x0 * MathData.y0 * MathData.y0 * MathData.y0 + MathData.q;
                    break;

                case 5:
                    MathData.x = MathData.general_MJ2 * MathData.x0 * MathData.x0 * MathData.x0 * MathData.x0 * MathData.x0 - MathData.general_MJ3 * 10 * MathData.x0 * MathData.x0 * MathData.x0 * MathData.y0 * MathData.y0 + MathData.general_MJ4 * 5 * MathData.x0 * MathData.y0 * MathData.y0 * MathData.y0 * MathData.y0 + MathData.p;
                    MathData.y = MathData.general_MJ3 * MathData.y0 * MathData.y0 * MathData.y0 * MathData.y0 * MathData.y0 - MathData.general_MJ4 * 10 * MathData.x0 * MathData.x0 * MathData.y0 * MathData.y0 * MathData.y0 + MathData.general_MJ5 * 5 * MathData.x0 * MathData.x0 * MathData.x0 * MathData.x0 * MathData.y0 + MathData.q;
                    break;
                default:
                    MathData.x = MathData.general_MJ2 * MathData.x0 * MathData.x0 - MathData.general_MJ3 * MathData.y0 * MathData.y0 + MathData.p;//对于给定的p和q，按照下面两行无限迭代。
                    MathData.y = MathData.general_MJ4 * 2 * MathData.x0 * MathData.y0 + MathData.q;
                    break;
            }
        }

        public static void dec_getNextIter(int Times)
        {
            switch (Times)
            {
                case 2:
                    MathData.dec_x = MathData.general_MJ2 * MathData.dec_x0 * MathData.dec_x0 - MathData.general_MJ3 * MathData.dec_y0 * MathData.dec_y0 + MathData.dec_p;//对于给定的p和q，按照下面两行无限迭代。
                    MathData.dec_y = MathData.general_MJ4 * 2 * MathData.dec_x0 * MathData.dec_y0 + MathData.dec_q;
                    break;
                case 3:
                    MathData.dec_x = MathData.general_MJ2 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_x0 - MathData.general_MJ3 * 3 * MathData.dec_x0 * MathData.dec_y0 * MathData.dec_y0 + MathData.dec_p;
                    MathData.dec_y = MathData.general_MJ4 * 3 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_y0 - MathData.general_MJ5 * MathData.dec_y0 * MathData.dec_y0 * MathData.dec_y0 + MathData.dec_q;
                    break;
                case 4:
                    MathData.dec_x = MathData.general_MJ2 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_x0 - MathData.general_MJ3 * 6 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_y0 * MathData.dec_y0 + MathData.general_MJ4 * MathData.dec_y0 * MathData.dec_y0 * MathData.dec_y0 * MathData.dec_y0 + MathData.dec_p;
                    MathData.dec_y = MathData.general_MJ5 * 4 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_y0 - MathData.general_MJ5 * 4 * MathData.dec_x0 * MathData.dec_y0 * MathData.dec_y0 * MathData.dec_y0 + MathData.dec_q;
                    break;

                case 5:
                    MathData.dec_x = MathData.general_MJ2 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_x0 - MathData.general_MJ3 * 10 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_y0 * MathData.dec_y0 + MathData.general_MJ4 * 5 * MathData.dec_x0 * MathData.dec_y0 * MathData.dec_y0 * MathData.dec_y0 * MathData.dec_y0 + MathData.dec_p;
                    MathData.dec_y = MathData.general_MJ3 * MathData.dec_y0 * MathData.dec_y0 * MathData.dec_y0 * MathData.dec_y0 * MathData.dec_y0 - MathData.general_MJ4 * 10 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_y0 * MathData.dec_y0 * MathData.dec_y0 + MathData.general_MJ5 * 5 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_x0 * MathData.dec_y0 + MathData.dec_q;
                    break;
                default:
                    MathData.dec_x = MathData.general_MJ2 * MathData.dec_x0 * MathData.dec_x0 - MathData.general_MJ3 * MathData.dec_y0 * MathData.dec_y0 + MathData.dec_p;//对于给定的p和q，按照下面两行无限迭代。
                    MathData.dec_y = MathData.general_MJ4 * 2 * MathData.dec_x0 * MathData.dec_y0 + MathData.dec_q;
                    break;
            }
        }

        #endregion
    }
}
